#!python
try:
    import pycurl2
except:
    import pycurl as pycurl2
import json
import StringIO
import urllib
import time
import ConfigParser

task_status=["success","downloading...","system error","resource not exists","timeout","resource exists but error","no enough space","file is exists","task canceled"]

class PcsOp:
    def __init__(self, access_token):
        self.access_token = access_token
        self.curl=pycurl2.Curl()
        self.curl.setopt(self.curl.SSL_VERIFYPEER,0)
        self.curl.setopt(self.curl.TIMEOUT, 20)
        self.curl.setopt(self.curl.FOLLOWLOCATION,1)
        self.curl.setopt(self.curl.MAXREDIRS, 5)
        self.curl.setopt(self.curl.HTTPHEADER,["Expect:"])
        self.curl.setopt(self.curl.VERBOSE, 1)

    def download_file(self, url, save_path=None):
        if not save_path:
            save_path = "/apps/WiFiDisk/download"
        request_url = "https://pcs.baidu.com/rest/2.0/pcs/services/cloud_dl"
        param1={"method":"add_task",
                "access_token":self.access_token,
                "save_path":save_path,
                "source_url":url,
                }
        param2={"method":"query_task",
                "access_token":self.access_token,
                "task_ids":"",
                "op_type":1
                }

        out=StringIO.StringIO()
        self.curl.setopt(self.curl.URL,request_url)
        self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
        self.curl.setopt(self.curl.POST, 1)
        self.curl.setopt(self.curl.POSTFIELDS,urllib.urlencode(param1))
        #c.setopt(c.VERBOSE,1)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        #print out.getvalue()
        result = json.loads(out.getvalue())
        if code != 200:
            print "code",code
            print "error_code: %d, error_msg: %s" % (result["error_code"], result["error_msg"])
            raise OSError("add task failed")

        task_id = result["task_id"]

        param2["task_ids"] = task_id

        while True:
            out.truncate(0)
            self.curl.setopt(self.curl.URL,request_url)
            self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
            self.curl.setopt(self.curl.POSTFIELDS, urllib.urlencode(param2))
            self.curl.perform()
            code = self.curl.getinfo(self.curl.RESPONSE_CODE)
            #print out.getvalue()
            if code != 200:
                print "code",code
                print "task not exists"
                raise OSError("task not exists")

            result = json.loads(out.getvalue())
            rs = result["task_info"]["%d" % task_id]["result"]
            status = result["task_info"]["%d" % task_id]["status"]
            if int(status) == 0:
                #print "success"
                break
            if int(status) != 1:
                print "error: %s" % task_status[int(status)]
                raise OSError("remote download error")
            time.sleep(5)
        out.close()
        #c.close()

    def delete_file(self, p):
        request_url="https://pcs.baidu.com/rest/2.0/pcs/file"
        param1={
                "method":"delete",
                "access_token":self.access_token,
                "path": p
                }
        u1="%s?%s" % (request_url,urllib.urlencode(param1))
        out=StringIO.StringIO()
        self.curl.setopt(self.curl.URL,u1)
        self.curl.setopt(self.curl.HTTPGET,1)
        self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        if code != 200:
            print "code",code
            print out.getvalue()
            raise OSError("delete file failed")
        out.close()
        #c.close()

    def get_filelist(self, d=None):
        if not d:
            d = "/apps/WiFiDisk/download"
        request_url="https://pcs.baidu.com/rest/2.0/pcs/file"
        param1={
                "method":"list",
                "access_token":self.access_token,
                "path":d,
                "by":"time",
                "order":"asc",
                "limit":"0-10"
                }
        u1="%s?%s" % (request_url,urllib.urlencode(param1))
        out=StringIO.StringIO()
        #c.setopt(c.VERBOSE,1)
        self.curl.setopt(self.curl.URL,u1)
        self.curl.setopt(self.curl.HTTPGET, 1)
        self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        result = json.loads(out.getvalue())
        if code != 200:
            print "code",code
            print "error_code: %d, error_msg: %s" % (result["error_code"], result["error_msg"])
            raise OSError("get file list failed")
        lts = result["list"]
        out.close()
        return lts

    def delete_all(self, flists):
        request_url="https://pcs.baidu.com/rest/2.0/pcs/file"
        param2={
                "method":"delete",
                "access_token":self.access_token,
                }
        out=StringIO.StringIO()
        files = []
        for f in flists:
            files.append(dict(path=f["path"]))
        p={"list":files}
        p2={"param":json.dumps(p)}

        u2="%s?%s" % (request_url, urllib.urlencode(param2))

        self.curl.setopt(self.curl.URL,u2)
        self.curl.setopt(self.curl.POST,1)
        self.curl.setopt(self.curl.POSTFIELDS,urllib.urlencode(p2))
        out.truncate(0)
        self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
        self.curl.perform()
        code=self.curl.getinfo(self.curl.RESPONSE_CODE)
        result = out.getvalue()
        if code != 200:
            print "code",code
            print result
            raise OSError("delete files failed")
        out.close()
        #c.close()

    def query_space(self):
        request_url="https://pcs.baidu.com/rest/2.0/pcs/quota"
        param1={
                "method":"info",
                "access_token":self.access_token,
                }
        u1="%s?%s" % (request_url, urllib.urlencode(param1))
        out=StringIO.StringIO()
        #c.setopt(c.VERBOSE,1)
        self.curl.setopt(self.curl.URL,u1)
        self.curl.setopt(self.curl.WRITEFUNCTION,out.write)
        self.curl.setopt(self.curl.HTTPGET, 1)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        if code != 200:
            print out.getvalue()
            raise OSError("query space failed")
        result=out.getvalue()
        d=json.loads(result)
        total=d["quota"]
        used=d["used"]
        out.close()
        return (used,total)

    def mkdir(self, p):
        request_url="https://pcs.baidu.com/rest/2.0/pcs/file"
        param1={
                "method":"mkdir",
                "access_token":self.access_token,
                "path":p,
                }
        out=StringIO.StringIO()
        #self.curl.setopt(self.curl.URL, request_url)
        self.curl.setopt(self.curl.HTTPGET, 1)
        u="%s?%s" % (request_url, urllib.urlencode(param1))
        self.curl.setopt(self.curl.URL, u)
        self.curl.setopt(self.curl.POSTFIELDS, urllib.urlencode(param1))
        self.curl.setopt(self.curl.WRITEFUNCTION,  out.write)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        result = json.loads(out.getvalue())
        if code != 200:
            if result["error_code"] != 31061:
                print code
                print out.getvalue()
                raise OSError("mkdir failed")
        out.close()

    def info(self, p):
        request_url="https://pcs.baidu.com/rest/2.0/pcs/file"
        param1={
                "method":"meta",
                "access_token":self.access_token,
                "path":p,
                }
        out=StringIO.StringIO()
        #self.curl.setopt(self.curl.URL, request_url)
        self.curl.setopt(self.curl.HTTPGET, 1)
        u="%s?%s" % (request_url, urllib.urlencode(param1))
        self.curl.setopt(self.curl.URL, u)
        self.curl.setopt(self.curl.POSTFIELDS, urllib.urlencode(param1))
        self.curl.setopt(self.curl.WRITEFUNCTION,  out.write)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        result = json.loads(out.getvalue())
        if code != 200:
            if result["error_code"] != 31061:
                print code
                print out.getvalue()
                raise OSError("info failed")
        out.close()
        return result["list"]

    def get_access_token(self, client_id, client_secret, refresh_token):
        request_url = "https://openapi.baidu.com/oauth/2.0/token"
        param={"grant_type":"refresh_token",
                "refresh_token":refresh_token,
                "client_id":client_id,
                "client_secret":client_secret
                }
        out=StringIO.StringIO()
        self.curl.setopt(self.curl.URL, request_url)
        self.curl.setopt(self.curl.POST, 1)
        self.curl.setopt(self.curl.POSTFIELDS, urllib.urlencode(param))
        self.curl.setopt(self.curl.WRITEFUNCTION, out.write)
        self.curl.perform()
        code = self.curl.getinfo(self.curl.RESPONSE_CODE)
        if code != 200:
            print "code",code
            print out.getvalue()
            raise OSError("get access_token failed")
        result = json.loads(out.getvalue())
        print result
        open("key.txt","w").write(json.dumps(result))
        out.close()

if __name__ == "__main__":
    d_url = "http://www.simicloud.com:9081/last.rmvb"
    cfg=ConfigParser.ConfigParser()
    cfg.read("server.cfg")
    access_token = cfg.get("server","access_token")
    app_key = cfg.get('server',"app_key")
    secret = cfg.get("server","client_secret")
    refresh_token=cfg.get("server","refresh_token")
    pcs = PcsOp(access_token)
    #pcs.get_access_token(app_key, secret, refresh_token)
    u,t=pcs.query_space()
    print u,t,float(u)/t
    #print pcs.info("/apps/WiFiDisk/download/last.rmvb")
    #pcs.download_file(d_url)
    #lsts=pcs.get_filelist()
    #print lsts
    #pcs.delete_all(lsts)

